package org.cloud.utils;

import cn.hutool.core.util.ReUtil;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import lombok.AllArgsConstructor;
import org.springframework.util.Assert;

public class PasswordValidatorUtil {

    @AllArgsConstructor
    public enum PasswordErrorEnum {
        PASSWORD_TOO_SHORT("password.error.tooShort", "密码长度必须至少为8个字符"),
        MISSING_UPPERCASE("password.error.missingUppercase", "密码必须包含至少一个大写字母"),
        MISSING_LOWERCASE("password.error.missingLowercase", "密码必须包含至少一个小写字母"),
        MISSING_DIGIT("password.error.missingDigit", "密码必须包含至少一个数字"),
        MISSING_SPECIAL_CHARACTER("password.error.missingSpecialCharacter", "密码必须包含至少一个特殊字符"),
        PASSWORD_VALID("password.success.valid", "密码强度合格"),
        ;

        public final String i18n;
        public final String desc;
    }

    @AllArgsConstructor
    public enum NumericPasswordErrorEnum {
        PASSWORD_TOO_SHORT("password.error.tooShort", "密码必须是6位数字"),
        NON_NUMERIC_PASSWORD("password.error.nonNumeric", "密码必须是纯数字"),
        COMMON_PASSWORD("password.error.commonPassword", "密码是常见的弱密码，请选择更复杂的密码"),
        REPETITIVE_DIGITS("password.error.repetitiveDigits", "密码不能是重复的数字"),
        FOUR_CONSECUTIVE_DIGITS("password.error.fourConsecutiveDigits", "密码不能包含连续四个重复的数字"),
        PASSWORD_VALID("password.success.valid", "密码有效"),
        ;

        public final String i18n;
        public final String desc;
    }

    // 常见的弱密码集合
    private static final Set<String> COMMON_PASSWORDS = new HashSet<>(Arrays.asList(
        "123456", "111111", "000000", "654321", "222222", "333333",
        "444444", "555555", "666666", "777777", "888888", "999999"
    ));

    // 8位强密码校验
    public static PasswordErrorEnum checkPasswordStrength(String password) {
        // 校验密码长度是否至少为8位
        if (password.length() < 8) {
            return PasswordErrorEnum.PASSWORD_TOO_SHORT;
        }

        // 校验是否包含至少一个大写字母
        if (!ReUtil.contains("[A-Z]", password)) {
            return PasswordErrorEnum.MISSING_UPPERCASE;
        }

        // 校验是否包含至少一个小写字母
        if (!ReUtil.contains("[a-z]", password)) {
            return PasswordErrorEnum.MISSING_LOWERCASE;
        }

        // 校验是否包含至少一个数字
        if (!ReUtil.contains("[0-9]", password)) {
            return PasswordErrorEnum.MISSING_DIGIT;
        }

        // 校验是否包含至少一个特殊字符
//        if (!ReUtil.contains("[@#$%.]", password)) {
//            return PasswordErrorEnum.MISSING_SPECIAL_CHARACTER;
//        }

        return PasswordErrorEnum.PASSWORD_VALID;
    }

    // 6位数字密码校验
    public static NumericPasswordErrorEnum checkNumericPassword(String password) {
        // 校验密码长度是否是6位
        if (password.length() != 6) {
            return NumericPasswordErrorEnum.PASSWORD_TOO_SHORT;
        }

        // 校验是否为纯数字
        if (!ReUtil.isMatch("\\d{6}", password)) {
            return NumericPasswordErrorEnum.NON_NUMERIC_PASSWORD;
        }

        // 校验是否为常见的弱密码
        if (COMMON_PASSWORDS.contains(password)) {
            return NumericPasswordErrorEnum.COMMON_PASSWORD;
        }

        // 校验是否为重复数字，例如"111111"
        if (password.chars().distinct().count() == 1) {
            return NumericPasswordErrorEnum.REPETITIVE_DIGITS;
        }

        // 校验是否包含连续四个相同的数字
        if (ReUtil.isMatch("(\\d)\\1{3,}", password)) {
            return NumericPasswordErrorEnum.FOUR_CONSECUTIVE_DIGITS;
        }

        return NumericPasswordErrorEnum.PASSWORD_VALID;
    }

    // 密码复杂度校验
    public static void checkNumericPasswordThrowError(String password) {
        NumericPasswordErrorEnum passCheckResult = checkNumericPassword(password);
        Assert.isTrue(NumericPasswordErrorEnum.PASSWORD_VALID.equals(passCheckResult), passCheckResult.i18n);
    }
    public static void checkPasswordStrengthThrowError(String password) {
        PasswordErrorEnum passCheckResult = checkPasswordStrength(password);
        Assert.isTrue(PasswordErrorEnum.PASSWORD_VALID.equals(passCheckResult), passCheckResult.i18n);
    }
}
